I've forgotten who sent me the question. I worked out the answer over a long period, eventually getting a clarification from Mike Kahl, the original author of THINK C. dgp.
QUESTION
"There was an elementary question about THINK C that I meant but forgot to ask you. Page 166 of THINK C's 'Standard Library Reference' talks of generic console Environment and Macintosh Environment and says you can't use use Mac Toolbox in the former. This doesn't seem to be true (we've programmed a lot in both environments) but it's always bothered me that it may contain some truth so it's a recurrent candidate for hypotheses about any problem that arises. Do you know exactly what truth it contains?"
ANSWER
The answer to this question is slightly involved. The fundamental choice you make is whether THINK C will initialize QuickDraw for you and subsequently process all keyboard input (via scanf, etc.) or whether you will initialize QuickDraw yourself and handle all keyboard input via GetNextEvent (scanf won't work). Quickdraw is initialized by a call to InitGraf. At the time of your first call to the console package, typically a printf, THINK checks to see if InitWindow has been called. If not then it calls InitGraf, InitWindows, etc., and handles all subsequent keyboard input.
That's the fundamental choice. However, there are also some incidental problems that needn't be, but which we have to live with. The author of THINK C, Michael Kahl, decided that people who include ANSI in their projects shouldn't also have to include MacTraps. Unfortunately his implementation of that results in duplicating the QuickDraw global area. So most of the QuickDraw globals, e.g. the color "gray", point to the wrong global area, and are useless.
Here's a copy of a "bug" report that I sent to Mike Kahl,
"This is a bug. As far as I can tell the quickdraw Patterns black, white, and gray are all zero (i.e. equivalent to white)."
and his reply,
"As far as your reported bug goes, I suspect the mistake is yours. I'm guessing you're running into this problem (QD patterns being wrong) in a context in which you have not called InitGraf. Remember, the "QuickDraw globals" are just variables in your own global space; they get filled in by InitGraf, which is why InitGraf takes &thePort as an argument. So in a non-application, or in an application running under the "console environment", the QuickDraw globals don't get initialized.
"The console code (in "console.c") calls InitGraf and the other Mac initialization calls, so you won't have to. Remember, the console stuff is designed to allow you to run vanilla stdio-based C code without modification. I made a decision early on that the ANSI library (which is where the console stuff lives) would not make any reference to MacTraps. In the past, users have been confused about having to load MacTraps as well as stdio, so I wanted to make the ANSI library completely self-contained. So throughout ANSI, if I needed to issue a call that's normally done through glue in MacTraps, I called it directly using inline assembly instead. Similarly, when I had to pass the address of some QuickDraw globals to InitGraf when doing the console stuff, I passed an address private to "console.c", rather than drag in MacTraps (which is where "thePort", "gray", etc., live).
"If you call InitGraf yourself, the console will still do one. I'm not sure what happens if InitGraf gets called twice, but my guess would be that the second call would override the first, making the first call's QuickDraw globals no longer be THE QuickDraw globals. Still, if all you care about is getting the patterns initialized, it might work. You might try it, but I'd feel safer copying the console's QuickDraw globals into yours, e.g.
asm {
movea.l (a5),a0
move.l -24(a0),gray
move.l -20(a0),gray+4
}
"If you get as far in your own initializations as InitWindow, the console won't do any of its own initializations, but then you're responsible for the whole event loop, etc. Also in this mode the consoles are write-only. This feature is there so you can have a "printf window" in your otherwise Mac-style application."
SOLUTION
Use the new VideoToolbox routines CopyQuickDrawGlobals(), which implements Mike Kahl's suggestion.